package com.tjbklx1.redis.chap05;

import java.util.HashMap;
import java.util.Map;

import redis.clients.jedis.Jedis;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.tjbklx1.redis.JedisUtil;

/**
 * 使用Redis存储配置信息
 * 
 * @author tjbklx1
 * @date 2018-12-6
 */
public class App58_Config {

	private static final Map<String, Map<String, Object>> CONFIGS = new HashMap<String, Map<String, Object>>();
	private static final Map<String, Long> CHECKED = new HashMap<String, Long>();
	public static final Map<String, Jedis> REDIS_CONNECTIONS = new HashMap<String, Jedis>();

	public static void main(String[] args) {
		Jedis conn = JedisUtil.getJedisWithDB();
		new App58_Config().testConfig(conn);
	}

	public void testConfig(Jedis conn) {
		System.out.println("\n----- testConfig -----");
		System.out.println("Let's set a config and then get a connection from that config...");
		Map<String, Object> config = new HashMap<String, Object>();
		config.put("db", 0);
		setConfig(conn, "redis", "test", config); // 初始化config

		Jedis conn2 = redisConnection("test");
		System.out.println("We can run commands from the configured connection: " + (conn2.info() != null));
	}

	/**
	 * 将config以GSON格式放到缓存中,KEY=config:type:component
	 * 
	 * @param conn
	 * @param type
	 * @param component
	 * @param config
	 */
	public void setConfig(Jedis conn, String type, String component, Map<String, Object> config) {
		Gson gson = new Gson();
		conn.set("config:" + type + ':' + component, gson.toJson(config)); // config:type:component
	}

	public Jedis redisConnection(String component) {
		Jedis configConn = REDIS_CONNECTIONS.get("config");
		if (configConn == null) {
			configConn = JedisUtil.getJedisWithDB();
			REDIS_CONNECTIONS.put("config", configConn);
		}

		String key = "config:redis:" + component;
		Map<String, Object> oldConfig = CONFIGS.get(key); // 获得 初始化config
		Map<String, Object> config = getConfig(configConn, "redis", component);

		if (!config.equals(oldConfig)) {
			Jedis conn = new Jedis("localhost");
			if (config.containsKey("db")) {
				conn.select(((Double) config.get("db")).intValue());
			}
			REDIS_CONNECTIONS.put(key, conn);
		}

		return REDIS_CONNECTIONS.get(key);
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> getConfig(Jedis conn, String type, String component) {
		int wait = 1000;
		String key = "config:" + type + ':' + component;

		Long lastChecked = CHECKED.get(key); //
		if (lastChecked == null || lastChecked < System.currentTimeMillis() - wait) {
			CHECKED.put(key, System.currentTimeMillis());
			String value = conn.get(key); // 从缓存中取 config:type:component 的值
			Map<String, Object> config = null;
			if (value != null) {
				Gson gson = new Gson();
				config = (Map<String, Object>) gson.fromJson(value, new TypeToken<Map<String, Object>>() {
				}.getType());
			} else {
				config = new HashMap<String, Object>();
			}
			CONFIGS.put(key, config); // 从 redis中取出config,覆盖初始化config
		}
		return CONFIGS.get(key);
	}
}
